import React from 'react';
import Tip from '../components/tip';
import '../less/updatefile.extend.less';

class FileReaderExtend{
	constructor(file, filetype, filesize){
		this.file = file;
		this.filetype = filetype;
		this.filesize = filesize;
		this.reader = new window.FileReader();
		return this;
	}
	on(name, func){
		this.reader["on"+name] = func;
		return this;
	}
	readData(){
		const reg = new RegExp(this.filetype.replace("/","\\/"));
		if (reg.test(this.file.type) && this.file.size < this.filesize * 1024 * 1024){
			this.reader.readAsBinaryString(this.file);
		}else{
			this.reader.onerror();
		}
		return this;
	}
}

class AJAX{
	constructor(options, res, func){
		this.xhr = new XMLHttpRequest();
		this.result = res;
		this.xhr.open(options.type, options.url, true);
		this.xhr.timeout = options.timeout;
		this.xhr.overrideMimeType(options.mimetype);
		func(this.xhr, res);
		return this;
	}
	on(name, func){
		this.xhr["on"+name] = func;
		return this;
	}
	send(){
		this.xhr.sendAsBinary && this.xhr.sendAsBinary(this.result);
		this.xhr.send && this.xhr.send(this.result);
		return this;
	}
}

export default class UpdateFile extends React.Component{
	constructor(props){
		super(props);
		this.state ={
			startTime:0,
			endTime:0,
			endval:0,
			altime:0,
			Lnum:0,
			calcspeed:0,
			progress:0,
			ajaxProgress:0,
			error:0,
			currentType:'wait',
			isShowTip: false
		}
		return this;
	}
	readerOnLoad(res){
		var that = this,
			ajax = new AJAX({
				type: "post",
				url: "",
				timeout: 300000,
				mimetype: "application/octet-stream"
			}, res, function(xhr, res){
				that.setState({
                	currentType: 'Update Start'
                });
				that.props.onFileUpdateStart(xhr, res);
			}).on("progress", function(e){
				if (e.lengthComputable) {
	                var percentComplete = e.loaded / e.total;
	                that.setState({
	                	ajaxProgress: percentComplete * 100
	                });
	                that.props.onFileUpdateProgress(percentComplete * 100, percentComplete, e);
	            }
			}).on("error", function(xhr, status, err){
				that.setState({
                	currentType: 'Error',
                	isShowTip: false
                });
				that.props.onFileUpdateError(xhr, status, err);
			}).on("load", function(e){
				that.setState({
                	currentType: 'Update Success',
                	isShowTip: false
                });
				that.props.onFileUpdated(e);
			}).send();
	}
	inputFileChange(e){
		let that = this,
			file = that.refs["updatefile"].files[0];
		that.setState({
			progress:0,
			ajaxProgress:0,
			calcspeed:0,
			error:0,
			isShowTip:true
		});
		that.props.onFileReadStart(file.type, file.size/1024, file.name);
		let reader = new FileReaderExtend(file, that.props.filetype, that.props.filesize);
		reader.on("loadstart", function(e){
			that.setState({
				startTime: new Date(),
				fileName: file.name,
				currentType: 'Reading'
			});
		}).on("load", function(e){
			that.setState({
				error: 1,
				currentType: 'Read Success'
			});
			that.props.onFileReaded(e);
			that.readerOnLoad(e.target.result);
		}).on("progress", function(e){
			let endTime = new Date(),
				altime = (e.loaded - (that.state.endval||0)) / (endTime - that.state.startTime),
				endval = e.loaded,
				Lnum = Math.pow(10, 2),
				calcspeed = Math.round(altime * Lnum) / Lnum,
				progress = ((e.loaded / e.total) * 100).toFixed(0),
				progressVal = progress+"%",
				calcspeedVal = calcspeed + "K/s";
			that.setState({
				endTime: endTime,
				altime: altime,
				endval: endval,
				Lnum: Lnum,
				calcspeed: calcspeed,
				progress: progress
			});
			that.props.onFileReadProgress(progressVal, calcspeedVal, e);
		}).on("error", function(e){
			that.props.onFileReadError({
				type: 4
			});
			that.setState({
				currentType: 'Error',
				error: file.size > that.props.filesize * 1024 * 1024 ? 2 : 3,
                isShowTip: false
			});
		}).readData();
	}
	render(){
		return (
			<div className="update_file_extend">
				<Tip isShowTip={this.state.isShowTip}>
					submitting data ...
				</Tip>
				<div className="update_file_extend_progress_main">
					<div className="update_file_extend_progress" style={{display:this.props.isShowProgress ? 'block' : 'none'}}>
						<span className="update_file_extend_progress_line" style={{width:this.state.progress+'%'}}></span>
						<span className="update_file_extend_progress_value">Read {this.state.progress}%</span>
					</div>
					<div className="update_file_extend_progress ajax" style={{display:this.props.isShowProgress ? 'block' : 'none'}}>
						<span className="update_file_extend_progress_line" style={{width:this.state.ajaxProgress+'%'}}></span>
						<span className="update_file_extend_progress_value">Update {this.state.ajaxProgress}%</span>
					</div>
				</div>
				<div className="update_file_extend_input" ref="updatefilebutton">
					{this.props.children}
					<input accept={this.props.filetype} className="update_file_input_item" type="file" onChange={this.inputFileChange.bind(this)} ref="updatefile" />
				</div>
			</div>
		)
	}
}